#include "netinet/in.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/socket.h"
#include "sys/types.h"
#include "unistd.h"

#define oops(m) \
  {             \
    perror(m);  \
    exit(1);    \
  }

int make_dgram_server_socket(char *ip, int portnum);
int get_internet_address(char *host, int len, int *port,
                         struct sockaddr_in *addrp);
void say_who_called(struct sockaddr_in *addrp);

int main(int ac, char *av[]) {
  int sock;
  char *ip = av[1];
  int portnum = atoi(av[2]);
  if ((sock = make_dgram_server_socket(ip, portnum)) == -1) {
    oops("make_dgram_server_socket");
  }

  struct sockaddr_in saddr;
  socklen_t saddrlen = sizeof(saddr);
  size_t msglen;
  char buf[BUFSIZ];
  while ((msglen = recvfrom(sock, buf, BUFSIZ, 0, (struct sockaddr *)&saddr,
                            &saddrlen)) > 0) {
    buf[msglen] = '\0';
    printf("dgrecv: got a message: %s\n", buf);
    say_who_called(&saddr);
    if (sendto(sock, buf, msglen, 0, (struct sockaddr *)&saddr, saddrlen) ==
        -1) {
      oops("sendto");
    }
  }
  return 0;
}

void say_who_called(struct sockaddr_in *addrp) {
  char host[BUFSIZ];
  int port;
  get_internet_address(host, BUFSIZ, &port, addrp);
  printf("from: %s:%d\n", host, port);
}